home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 6
/
Sonderheft_6-96.iso
/
pd
/
disktools
/
kopieren
/
afcopy v4.4
/
sourcecode
/
afcopy_file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-03
|
19KB
|
768 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <time.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <exec/nodes.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/filehandler.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/reqtools.h>
#include <libraries/dos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/reqtools_protos.h>
#include "afcopy_defines.h"
#include "afcopy_protos.h"
#include "afcopy_version.h"
#include "afcopy_vars.h"
void getfiles(short side, char *path)
{
BPTR FL;
struct FileInfoBlock *FB;
long err;
char errormsg[600],iomsg[50];
#ifdef DEBUG
puts("getfiles()");
#endif
pathok[side]=FALSE;
clearside(side);
SetAPen(W->RPort,2);
/* SetBPen(W->RPort,0);*/ /*assume backgroung is color 0 due to clearfiles()*/
OutTextXY(W,filexpos[side]+50,topborder+50,"Reading Directory...");
totalfiles[side]=0;
selectedfiles[side]=0;
selectedsize[side]=0;
if ((FL=Lock(path,(long)ACCESS_READ))==NULL)
{
err=IoErr();
if (!(err==226 && ignorenodisk))
{
IoErrMsg(iomsg,err);
sprintf(errormsg,"Error Getting Directory!\n%s\n%s",path,iomsg);
rtEZRequest (errormsg,okmsg,NULL,(struct TagItem *)&reqtags,NULL);
}
}
else
{
NameFromLock(FL,cpath[side],MAX_PATH_LEN);
addterm(cpath[side]);
FB=malloc(sizeof(struct FileInfoBlock));
err= !Examine(FL,FB);
if (!err)
{
pathok[side]=TRUE;
do
{
err=!ExNext(FL,FB);
if (!err)
{
if (totalfiles[side] < MAX_FILES_IN_LIST)
{
if (FB->fib_DirEntryType!=0)
{
if (ignorehiddenbit || (!ignorehiddenbit && !(FB->fib_Protection & 1<<7)))
{
if (allocmemforname(side))
{
strcpy(filename[side][totalfiles[side]],FB->fib_FileName);
filesize[side][totalfiles[side]]=FB->fib_Size;
filetype[side][totalfiles[side]]=FB->fib_DirEntryType<0 ? -1 : 1;
filetags[side][totalfiles[side]]=FALSE;
/* strcpy(errormsg,cpath[side]);
strcat(errormsg,FB->fib_FileName);
filedate[side][totalfiles[side]]=getft(errormsg);
*/
filedate[side][totalfiles[side]]=FB->fib_Date;
totalfiles[side]++;
if ((totalfiles[side]%20)==0) updateslider(side,0);
}
else
{
rtEZRequest("no memory left!!","Bogus",NULL,(struct TagItem *)&reqtags,NULL);
}
}
}
else
{
rtEZRequest ("Encountered A Strange File Entry!","Hmm, I'l check my disk",NULL,(struct TagItem *)&reqtags,NULL);
}
}
}
} while (!err);
}
free(FB);
UnLock(FL);
}
updateslider(side,0);
qsortfiles(side,0,totalfiles[side]-1);
clearside(side);
DoDiskInfo(side,cpath[side]);
}
/*
* i'd just like to thank the author of format for the follow bit of
* code, some of which is nicked from his source.
*/
void findvolumes(short side)
{
struct DosList *DosList;
struct DeviceNode *DevNode;
UBYTE *Pointer;
char string[32]="";
int loop;
pathok[side]=FALSE;
totalfiles[side]=0;
selectedfiles[side]=0;
selectedsize[side]=0;
clearside(side);
DosList = LockDosList(LDF_ALL|LDF_READ);
while(DosList = NextDosEntry(DosList,LDF_ALL|LDF_READ))
{
DevNode = (struct DeviceNode *)DosList;
if (DevNode->dn_Type==DLT_DIRECTORY || DevNode->dn_Type==DLT_VOLUME)
{
Pointer = (UBYTE *)BADDR(DevNode -> dn_Name);
if (Pointer[0])
{
for(loop = 0 ; loop < Pointer[0] ; loop++)
string[loop] = Pointer[loop + 1];
string[Pointer[0]] = 0; /* terminate string */
strcat(string,":");
AddToFileList(side,string,0,1,FALSE);
}
}
}
UnLockDosList(LDF_ALL|LDF_READ);
qsortfiles(side,0,totalfiles[side]-1);
strcpy(cpath[side],"");
updatepath(side);
displayoffset[side]=0;
updateslider(side,0);
displayfilelist(side,0);
}
LONG getfilesize(char *filename)
{
BPTR FL;
struct FileInfoBlock *FB;
LONG retval=-1;
#ifdef DEBUG
puts("getfilesize()");
#endif
if (FL=Lock(filename,(long)ACCESS_READ))
{
if(FB=malloc(sizeof(struct FileInfoBlock)))
{
if (Examine(FL,FB))
{
retval=FB->fib_Size;
}
free(FB);
}
UnLock(FL);
}
return(retval);
}
int ModifyComment(char *filename,BOOL usedefcomm)
{
/* return -1 if ALL was pressed */
char comment[MAX_COMMENT_LEN+1];
int errnum=0;
BPTR FL;
struct FileInfoBlock *FB;
int doit=1;
#ifdef DEBUG
puts("ModifyComment()");
#endif
if (!usedefcomm)
{
if ((FL=Lock(filename,(long)ACCESS_READ))==NULL)
{
errnum=IoErr();
}
else
{
if(FB=malloc(sizeof(struct FileInfoBlock)))
{
errnum= !Examine(FL,FB);
if (!errnum)
{
strcpy(comment,FB->fib_Comment);
free(FB);
}
UnLock(FL);
}
else
{
errnum=103; /* NO MEM! */
}
}
}
else
{
strcpy(comment,defaultcomment);
}
if (!errnum)
{
if (!usedefcomm)
{
switch(rtGetString (comment, MAX_COMMENT_LEN, "Modify Comment", NULL,
RTGS_GadFmt, "Ok|ALL|Cancel",
RT_Window,W,
TAG_END))
{
case 2:
strcpy(defaultcomment,comment);
doit=2;
break;
case 0:
doit=0;
break;
}
}
if (doit)
{
SetComment(filename,comment);
errnum=IoErr();
if (!errnum && doit==2) errnum=-1;
}
}
return(errnum);
}
int filecopy(char *fromname,char *toname)
{
/*
* Simple function to copy a file, return IoErr if it fails, else it returns 0
* (if it fails it *will* delete the destination file if it exists.)
*/
LONG f1,f2;
ULONG *buf;
ULONG allocd,fromsize,nr,nw; /* ho ho ho, I forget to add the U to uword the first time..... */
/* makes life interesting when you can only copy files less than*/
/* 32768 bytes long......... hehehe!! */
BOOL cancel=FALSE,ChangedIt=FALSE,overwrite=FALSE;
int errnum=0;
BPTR FL;
struct FileInfoBlock *FB;
UWORD prot=240;
char reqstr[300]="\0";
#ifdef DEBUG
puts("filecopy()");
#endif
actuallytransferred=AT_NO;
if (FB=malloc(sizeof(struct FileInfoBlock)))
{
if ((FL=Lock(fromname,(long)ACCESS_READ))==NULL)
{
errnum=IoErr();
}
else
{
errnum= !Examine(FL,FB);
if (!errnum)
{
prot=FB->fib_Protection;
fromsize=FB->fib_Size;
}
UnLock(FL);
if (prot & FIBF_READ)
{
if ((!setprotverify) || ((setprotverify) && (rtEZRequest("File Protected From Reading!\n"
"Shall I change the protection for a mo ?",
"_Ok|_Dont you dare!",NULL,(struct TagItem *)&reqtags,NULL))))
{
ChangedIt=TRUE;
SetProtection(fromname,240);
}
}
}
if ((f1=Open(toname,MODE_OLDFILE))!=NULL)
{
IoErr(); // Clear IO Error..
ExamineFH(f1,FB);
if (autooverwrite)
{
overwrite=TRUE;
}
else
{
if (!skipall)
{
sprintf(reqstr,"Destination File Exists!\nNEW: %-32s %ld\nOLD: %-32s %ld\nOverwrite ?",fromname,fromsize,toname,FB->fib_Size);
switch (rtEZRequest(reqstr,"_Yes|_All|_Skip|Sk_ip All|_Rename|_Cancel",NULL,(struct TagItem *)&reqtags,NULL))
{
case 0: // Cancel
cancel=TRUE;
errnum=1;
break;
case 1: // YES
overwrite=TRUE;
break;
case 2: // ALL
tempautooverwrite=TRUE;
autooverwrite=TRUE;
overwrite=TRUE;
break;
case 3: // Skip
cancel=TRUE;
errnum=203; // object exists..
break;
case 4: // SkipAll
skipall=TRUE;
break;
case 5: // Rename
if (rtGetString(toname,MAX_PATH_LEN,"Enter New Name",NULL,RTGS_GadFmt, "Ok|Cancel",RT_Window,W,TAG_END)==0)
{
cancel=TRUE;
}
break;
}
}
if (skipall) cancel=TRUE;
}
Close(f1);
}
free(FB);
}
if (!cancel)
{
if ((f1=Open(fromname,MODE_OLDFILE))!=NULL)
{
if ((f2=Open(toname,MODE_NEWFILE))!=NULL)
{
allocd=0;
if (fromsize>max_copy_buf_size) fromsize=max_copy_buf_size;
if ((buf=AllocMem(fromsize,MEMF_PUBLIC))!=NULL)
{
allocd=fromsize;
}
if ((allocd==0) && (buf=AllocMem(COPYBUFSIZE,MEMF_PUBLIC))!=NULL)
{
allocd=COPYBUFSIZE;
}
if (allocd)
{
do
{
if (!(cancel=CheckStatCancel() ))
{
nr=Read(f1,buf,allocd);
nw=Write(f2,buf,nr);
}
} while (nr==nw && nr!=0 && !cancel);
if (nr!=nw)
{
errnum=IoErr();
if (!errnum) errnum=224;
}
FreeMem(buf,allocd);
if (cancel) errnum=1;
}
else
{
errnum=103; /* NO FREE STORE! */
}
Close(f2);
if (errnum)
{
DeleteFile(toname);
IoErr(); /* Clear IO Error */
}
}
else
{
errnum=IoErr();
}
Close(f1);
}
else
{
errnum=IoErr();
}
}
if (!errnum && !cancel)
{
if ((FL=Lock(fromname,(long)ACCESS_READ))==NULL)
{
errnum=IoErr();
}
else
{
FB=malloc(sizeof(struct FileInfoBlock));
errnum= !Examine(FL,FB);
if (!errnum)
{
SetComment(toname,FB->fib_Comment);
SetProtection(toname,prot);
SetFileDate(toname,&FB->fib_Date);
free(FB);
if (!overwrite) actuallytransferred=AT_YES;
else actuallytransferred=AT_OVERW;
}
UnLock(FL);
}
}
// moved from underneath the UnLock() above as it'd not get done if there was
// an error during the filecopying itself..
if (ChangedIt) SetProtection(fromname,prot);
return(errnum);
}
int filenuke(char *nukename)
{
int errnum;
#ifdef DEBUG
puts("filenuke()");
#endif
DeleteFile(nukename);
errnum=IoErr();
if (errnum)
{
SetProtection(nukename,240);
errnum=IoErr();
if (!errnum)
{
DeleteFile(nukename);
errnum=IoErr();
}
}
return(errnum);
}
int fileswap(char *fromname,char *toname)
{
int errnum=0;
#ifdef DEBUG
puts("fileswap()");
#endif
if (!Rename(fromname,toname))
{
errnum=filecopy(fromname,toname);
if (errnum<=0)
{
errnum=filenuke(fromname);
}
}
else actuallytransferred=AT_YES;
return(errnum);
}
void Makedir(short side)
{
char strbuf[MAX_PATH_LEN+1];
BPTR FL;
int errnum;
#ifdef DEBUG
puts("Makedir()");
#endif
if (pathok[side])
{
strcpy(strbuf,cpath[side]);
addterm(strbuf);
if (rtGetString (strbuf, MAX_PATH_LEN, "Enter Directory Name", NULL,RT_Window,W, TAG_END))
{
if (strlen(FilePart(strbuf))>30)
{
rtEZRequest("Name Too Long!","Bogus!",NULL,(struct TagItem *)&reqtags,NULL);
}
else
{
FL=CreateDir(strbuf);
if (FL==NULL)
{
rtEZRequest ("Error Creating Directory","Bogus",NULL,(struct TagItem *)&reqtags,NULL);
}
else
{
UnLock(FL);
if (SameDir(strbuf,cpath[side]))
{
if (AddToFileList(side,FilePart(strbuf),0,1,FALSE)) Updatedisplay(side);
}
if (rtEZRequest("Do you want an icon ?","Yes|No",NULL,(struct TagItem *)&reqtags,NULL))
{
strfcat(strbuf,".info",MAX_PATH_LEN);
errnum=filecopy(defaulticonfile,strbuf);
if (errnum) DosError("Error Copying Icon File",defaulticonfile,errnum);
if (!errnum && SameDir(strbuf,cpath[side]))
{
if (AddToFileList(side,FilePart(strbuf),getfilesize(strbuf),-1,FALSE)) Updatedisplay(side);
}
}
}
} /* it's attack of the killer pretty patterns!!! */
} /* sorry, I just couldnt resist it... :-0 */
}
}
int DirFunc(char *dirname,char *todirname,int mode)
{
char fname[MAX_PATH_LEN+1],tofname[MAX_PATH_LEN+1];
BOOL cancel=FALSE;
int FuncErr=0;
BPTR FL;
struct FileInfoBlock *FB;
long err;
int rret=FALSE;
#ifdef DEBUG
puts("DirFunc()");
#endif
/* attempt a rename on a swap command for a directory */
if (mode==G_Swap)
{
rret=Rename(dirname,todirname);
}
if ((!rret && mode==G_Swap) || mode!=G_Swap)
{
switch (mode)
{
case G_Swap:
case G_Copy:
if ((FL=CreateDir(todirname))!=NULL)
{
UnLock(FL);
}
break;
}
if ((FL=Lock(dirname,(long)ACCESS_READ))==NULL)
{
FuncErr=IoErr();
}
else
{
FB=malloc(sizeof(struct FileInfoBlock));
err= !Examine(FL,FB);
if (!err)
{
do
{
cancel=CheckStatCancel();
handlerefresh();
if (!cancel)
{
FuncErr=0;
if (mode==G_Delete)
{
// changed for v4.2, since i got a 2.04 machine I've found a bug
// when deleting files in the ram disk:
// so this always reads the first enry in the dir..
if (!(err= !Examine(FL,FB)))
{
err=!ExNext(FL,FB);
}
}
else
{
err=!ExNext(FL,FB);
}
if (!err)
{
strcpy(fname,dirname);
addterm(fname);
strfcat(fname,FB->fib_FileName,MAX_PATH_LEN);
strcpy(tofname,todirname);
addterm(tofname);
strfcat(tofname,FB->fib_FileName,MAX_PATH_LEN);
if (FB->fib_DirEntryType<0)
{ /* FILE */
switch (mode)
{
case G_Delete:
UpdateStat(0,0,"Delete",dirname,"",FB->fib_FileName);
FuncErr=filenuke(fname);
break;
case G_Copy:
UpdateStat(0,0,"Copy",dirname,todirname,FB->fib_FileName);
FuncErr=filecopy(fname,tofname);
break;
case G_Swap:
UpdateStat(0,0,"Swap",dirname,todirname,FB->fib_FileName);
FuncErr=fileswap(fname,tofname);
break;
}
}
else
{
if (FB->fib_DirEntryType>0)
{
switch (mode)
{
case G_Delete:
UpdateStat(0,0,"Delete",dirname,"",FB->fib_FileName);
FuncErr=DirFunc(fname,NULL,mode);
break;
case G_Copy:
UpdateStat(0,0,"Copy",dirname,todirname,FB->fib_FileName);
FuncErr=DirFunc(fname,tofname,mode);
break;
case G_Swap:
UpdateStat(0,0,"Swap",dirname,todirname,FB->fib_FileName);
FuncErr=DirFunc(fname,tofname,mode);
break;
}
}
else
{
rtEZRequest ("Encountered A Strange File Entry!","Hmm, I'll check my disk",NULL,(struct TagItem *)&reqtags,NULL);
}
}
if (FuncErr>1)
{
DosError("Error On File/Dir",fname,FuncErr);
}
}
if (FuncErr==1) cancel=TRUE;
}
else
{
FuncErr=1; /* CANCEL */
}
} while (!err && !cancel);
}
UnLock(FL);
free(FB);
if (!cancel /*&& !FuncErr*/ )
{
switch (mode)
{
case G_Swap:
case G_Delete:
DeleteFile(dirname);
FuncErr=IoErr();
break;
}
}
}
}
return(FuncErr);
}
long ExecCommand(char *command,BOOL asynch,BOOL shuffle)
{
static ULONG sysargs[] =
{
SYS_Input,NULL,
SYS_Output,NULL,
SYS_Asynch,FALSE, /* add option to this */
SYS_UserShell,TRUE,
NP_Priority,0L,
TAG_DONE
};
BPTR outputfile;
long retval=0;
char constr[500];
remspaces(command,command);
if (shuffle && customscreenopen) ScreenToBack(mysc);
sysargs[5]=asynch ? TRUE : FALSE;
replace(constr,outputcon,"@S@",screenname);
if (sysargs[5]) /* open a new window if asynch otherwise use normal one */
{
outputfile = Open(constr,MODE_OLDFILE);
}
else
{
/* test to see if one is already open, if not open it! */
if (outputconfile==NULL) outputconfile = Open(constr,MODE_OLDFILE);
outputfile=outputconfile;
}
if (outputfile) /* have we got an output file ? */
{
sysargs[1]=(ULONG)outputfile;
retval=SystemTagList(command,(struct TagItem *)sysargs);
if (shuffle && customscreenopen && !asynch) ScreenToFront(mysc);
}
return(retval);
}
void DoFormat( void )
{
char *pmsg="Yes|No";
LONG which,FFS,DC,ICONS,QUICK;
char cmdstr[81]="\0",name[33]="\0";
if ((which=rtEZRequest("Format What Drive ?","DF_0:|DF_1:|DF_2:|DF_3:|_CANCEL",NULL,(struct TagItem *)&reqtags,NULL))
&& (rtGetString (name, 32, "Enter Volume Name", NULL,RT_Window,W, TAG_END))
&& (name[0]!='\0'))
{
FFS=rtEZRequest("Fast File System ?",pmsg,NULL,(struct TagItem *)&reqtags,NULL);
DC=rtEZRequest("Directory Cache ?",pmsg,NULL,(struct TagItem *)&reqtags,NULL);
ICONS=rtEZRequest("Trashcan ?",pmsg,NULL,(struct TagItem *)&reqtags,NULL);
QUICK=rtEZRequest("QuickFormat ?",pmsg,NULL,(struct TagItem *)&reqtags,NULL);
sprintf(cmdstr,"FORMAT DRIVE DF%d: NAME %s %s %s %s %s",which-1,name,FFS ? "FFS" : "",DC ? "DIRCACHE" : "",ICONS ? "" : "NOICONS",QUICK ? "QUICK" : "");
ExecCommand(cmdstr,TRUE,shufflescreens);
}
}
void cdto( char *path )
{
BPTR FL,NFL;
if (FL=Lock(path,(long)ACCESS_READ))
{
NFL=CurrentDir(FL);
UnLock(NFL);
}
}